home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
fg
/
qf2
/
loadgame.c
< prev
next >
Wrap
Text File
|
1995-04-09
|
16KB
|
472 lines
/**********************************************************************\
* *
* LOADGAME.C *
* *
* Copyright 1993, 1995 Diana Gruber. All Rights Reserved. *
* Last modified: April 10, 1995 *
* *
* This source code is provided "as is" without any warranties, etc. *
* *
* Load the data files, initialize the graphics environment, handle *
* text, termination, and some other miscellaneous functions. *
* This file contains just about all the functions that are not *
* critical to game animation. Those functions are all in the file *
* QF.C. They are grouped in a single source code file so they can *
* be declared "near" for a slight speed boost. Functions in this *
* file are assumed to be far if compiled in real mode using the *
* medium model. *
* *
* For readibility, functions are stored alphabetically. *
* *
\**********************************************************************/
#define loadgame
#include "defs.h"
/**********************************************************************\
* *
* clear_layout *
* Set the layout array to all zeros *
* *
\**********************************************************************/
void clear_layout()
{
register short i,j;
for (i = 0; i < 22; i++)
for (j = 0; j < 15; j++)
layout[hidden][i][j] = FALSE;
}
/**********************************************************************\
* *
* fcopy_array *
* copy a string from far memory to near memory *
* (unnecessary in protected mode) *
* *
\**********************************************************************/
void fcopy_array(char far *s, char *t, short nchar)
{
register short i;
for (i = 0; i < nchar; i++)
*s++ = *t++;
}
/**********************************************************************\
* *
* getseed -- get a seed for the random number generator *
* *
\**********************************************************************/
void getseed()
{
seed = (short)(fg_getclock() & 0x7FFF);
}
/**********************************************************************\
* *
* init_globals *
* create player and score objects and initialize some global *
* variables *
* *
\**********************************************************************/
void init_globals()
{
char *array;
SPRITE *image;
/* create the score object */
array = (char *)malloc(60*5+1);
score = (OBJp)malloc(sizeof(OBJ)+1);
score->action = &new_score; /* does this work? integer address requires "near" declaration
which means it should be in the same source code file. Hmmm */
image = (SPRITE *)malloc(sizeof(SPRITE)+1);
image->bitmap = array;
image->height = 5;
image->width = 60;
image->xoffset = 0;
image->yoffset = 0;
score->image = image;
/* create the player object */
player = (OBJp)malloc(sizeof(OBJ)+1);
player->x = 26;
player->y = 164;
player->frame = 0;
player->xspeed = -8;
player->max_xspeed = 8;
player->yspeed = 0;
player->tile_xmin = 2;
player->tile_xmax = 16;
player->tile_ymin = 5;
player->attached_sprite = (OBJp)NULL;
player->tile_ymax = 10;
player->image = fighter[0];
/* initialize some global variables */
player_timer = 0;
player_time_target = 75;
bullet_count = 0;
nhits = 0;
hit_value = 990;
player_score = 0L;
scrolled = FALSE;
frame_count = 0;
nbullets = 0;
nenemies = 0;
autopilot = FALSE;
/* origin coordinates */
tile_orgx = 0;
tile_orgy = 0;
screen_orgx = 0;
screen_orgy = 0;
vpo = 0;
hpo = 240;
vpb = vpo+239;
hpb = hpo+239;
tpo = 480;
visual = 0;
hidden = 1;
/* start the random number generator */
getseed();
}
/**********************************************************************\
* *
* init_graphics -- initialize the graphics environment *
* *
\**********************************************************************/
void init_graphics()
{
#ifdef ModeX
fg_setmode(20); /* Mode X at a 320*200 resolution */
fg_resize(352,727);
#else
fg_setmode(19); /* Mode 13h */
fg_vbinit();
if ((virtbuff1 = (char *)malloc(352*727)) == (char *)NULL)
{
sprintf(abort_string,"out of virtual buffer memory");
terminate_game();
}
workvb = fg_vbdefine(virtbuff1,352,727);
fg_vbopen(workvb);
#endif
/* uncomment this line to turn off the vertical retrace */
// fg_waitvr(0);
}
/**********************************************************************\
* *
* intro_screens *
* Display the title screen and the credits screen *
* *
\**********************************************************************/
void intro_screens()
{
register short i;
char *array;
short x;
/* display title screen, copy to visual */
fg_move(0,hpo);
#ifdef ModeX
fg_showpcx("qf1.pcx",2);
fg_transfer(0,319,hpo,hpb,0,vpb,0,0);
#else
fg_loadpcx("qf1.pcx",2);
fg_vbpaste(0,319,hpo,hpo+199,0,199);
#endif
fg_waitfor(32);
}
/**********************************************************************\
* *
* irandom *
* Generate a pseudo-random number between any two integers. *
* *
\**********************************************************************/
irandom(short min, short max)
{
register short temp;
temp = seed ^ (seed >> 7);
seed = ((temp << 8) ^ temp) & 0x7FFF;
return((seed % (max-min+1)) + min);
}
/**********************************************************************\
* *
* load_level *
* Read the level information from a file *
* *
\**********************************************************************/
void load_level()
{
register short i,j;
char buffer[MAXROWS];
fg_move(0,480);
#ifdef ModeX
/* display the pcx file containing the tiles */
fg_showpcx("QF.PCX",2);
#else
/* load the pcx file containing the tiles into a virtual buffer*/
fg_loadpcx("QF.PCX",2);
#endif
/* open the level file containing the map information */
if ((tstream = fopen("QF.LEV","rb")) == NULL)
{
sprintf(abort_string,"QF.LEV not found");
terminate_game();
}
/* read the number of rows and columns */
fread(&ncols,sizeof(short),1,tstream);
fread(&nrows,sizeof(short),1,tstream);
/* read all the rows */
for (i = 0; i < ncols; i++)
{
fread(buffer,sizeof(char),nrows,tstream);
fcopy_array(&backtile[i][0],buffer,nrows);
}
fclose(tstream);
/* rows must be even -- adjust for odd number of rows */
if (ncols%2 != 0)
ncols--;
/* calculate the maximum world coordinates */
world_maxx = ncols*16-1;
world_maxy = nrows*16-1;
/* add another 22 columns at the end of the array for circular scroll */
for (i = 0; i < 22; i++)
{
for (j = 0; j < nrows; j++)
backtile[ncols+i][j] = backtile[i+54][j];
}
ncols+=22;
}
/**********************************************************************\
* *
* load_sprite *
* Read the bitmapped sprites from a file and store them in *
* structures. *
* *
\**********************************************************************/
void load_sprite()
{
register short i,n;
short nbytes;
char *bitmap;
short width,height;
SPRITE *new_sprite;
/* open the bitmap file i you can find it */
if ((tstream = fopen("QF.BMP","rb")) == NULL)
{
sprintf(abort_string,"QF.BMP not found");
terminate_game();
}
i = 0;
/* how many sprites are we talking about? */
fread(&nsprites,sizeof(short),1,tstream);
/* read all the sprites */
for (n = 0; n < nsprites; n++)
{
/* read the width and height and calculate the size of the bitmap */
fread(&width,sizeof(short),1,tstream);
fread(&height,sizeof(short),1,tstream);
nbytes = width * height;
/* allocate space for the bitmap */
if ((bitmap = (char *)malloc(nbytes)) == (char *)NULL)
{
sprintf(abort_string,"nsprites=%d n=%d width=%d height=%d nbytes=%d\n",
nsprites,n,width, height, nbytes);
terminate_game();
}
/* allocate space for the sprite, which is a structure including
the pointer to the previously allocated bitmap */
if ((new_sprite = (SPRITE *)malloc(sizeof(SPRITE)+1)) == (SPRITE *)NULL)
{
sprintf(abort_string,"Out of sprite memory");
terminate_game();
}
/* put this pointer in the sprite array */
sprite[i] = new_sprite;
/* now read the bitmap */
fread(bitmap,sizeof(char),nbytes,tstream);
/* initialize the sprite variables */
sprite[i]->bitmap = bitmap;
sprite[i]->width = width;
sprite[i]->height = height;
sprite[i]->xoffset = 0;
sprite[i]->yoffset = 0;
i++;
}
fclose(tstream);
/* assign sprites to the fighter arrays and give them y offsets */
fighter[0] = sprite[0];
fighter[1] = sprite[9];
fighter[2] = sprite[1];
fighter[3] = sprite[10];
fighter[4] = sprite[3];
fighter[5] = sprite[11];
fighter[6] = sprite[2];
fighter[7] = sprite[12];
/* also create an explosion array */
for (i = 0; i < 11; i++)
explosion[i] = sprite[i+14];
/* center the fighter */
for (i = 0; i < 8; i++)
{
fighter[i]->yoffset = fighter[i]->height/2 - fighter[2]->height/2;
}
/* center the explosions */
for (i = 1; i < 11; i++)
{
explosion[i]->xoffset = explosion[0]->width - explosion[i]->width/2;
explosion[i]->yoffset = explosion[i]->height/2 - explosion[0]->height;
}
}
/**********************************************************************\
* *
* put_btext *
* *
* This is a simple, efficient character font. Capital letters only. *
* Not all the characters are included, only the ones we need. *
* The letters are defined as 5 x 5 single color bitmaps. *
* *
\**********************************************************************/
char chars[37][5] = {
0, 0, 0, 0, 0,
-120, -8,-120, 80, 32, /* a */
-16,-120, -16,-120, -16, /* b */
120,-128,-128,-128, 120, /* c */
-16,-120,-120,-120, -16, /* c */
-8,-128, -16,-128, -8, /* e */
-128,-128, -16,-128, -16, /* f */
112,-120,-104,-128, 120, /* g */
-120,-120, -8,-120,-120, /* h */
112, 32, 32, 32, 112, /* i */
96,-112, 16, 16, 56, /* j */
-120,-112, -32,-112,-120, /* k */
-8,-128,-128,-128,-128, /* l */
-120, -88, -88, -40,-120, /* m */
-120,-104, -88, -56,-120, /* n */
112,-120,-120,-120, 112, /* o */
-128,-128, -16,-120, -16, /* p */
120, -88,-120,-120, 112, /* q */
-112, -96, -16,-120, -16, /* r */
-16, 8, 112,-128, 120, /* s */
32, 32, 32, 32, -8, /* t */
112,-120,-120,-120,-120, /* u */
32, 80,-120,-120,-120, /* v */
-120, -40, -88, -88,-120, /* w */
-120, 80, 32, 80,-120, /* x */
32, 32, 32, 80,-120, /* y */
-8, 64, 32, 16, -8, /* x */
112,-120,-120,-120, 112, /* 0 */
112, 32, 32, 96, 32, /* 1 */
-16, 64, 32,-112, 96, /* 2 */
-32, 16, 96, 16, -32, /* 3 */
16, 16, -16,-112,-112, /* 4 */
112, 8, -16,-128, -8, /* 5 */
112,-120, -16,-128, 112, /* 6 */
64, 64, 32, 16, -8, /* 7 */
112,-120, 112,-120, 112, /* 8 */
16, 8, 120,-120, 112, /* 9 */
};
put_bstring(char *string,short nchar,short ix,short iy)
{
register short i;
short blank;
char ch;
for (i = 0; i < nchar; i++)
{
blank = FALSE;
ch = string[i];
/* upper case */
if (ch >= 65 && ch <= 90)
ch -= 64;
/* lower case */
else if (ch >= 97 && ch <= 122)
ch -= 96;
/* numbers */
else if (ch >= 48 && ch <= 57)
ch -= 21;
else
blank = TRUE;
fg_move(ix,iy);
if (!blank) fg_drawmap(&chars[ch][0],1,5);
ix += 6;
}
return(0);
}
/**********************************************************************\
* *
* terminate_game *
* If for some reason we can't continue, like for example if a data *
* file is missing, do an abnormal termination. *
* *
\**********************************************************************/
void terminate_game()
{
/* disable the keyboard handler */
fg_kbinit(0);
/* close the virtual buffers */
fg_vbclose();
/* set the video mode to text mode */
fg_setmode(3);
/* reset the screen attributes (if ANSI.SYS is loaded ) */
fg_reset();
/* print the exit screen and exit */
printf(abort_string);
printf("\n");
exit(0);
}